cmake_minimum_required(VERSION 3.10)
project(easy_grpc VERSION 0.2.2)

find_package(protobuf)
find_package(gRPC)
find_package(var_futures)

include(GNUInstallDirs)
include(CTest)

# Check if easy_grpc is being used directly or via add_subdirectory, but allow overriding
if (NOT DEFINED EASY_GRPC_MASTER_PROJECT)
    if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
        set(EASY_GRPC_MASTER_PROJECT ON)
    else()
        set(EASY_GRPC_MASTER_PROJECT OFF)
    endif()
endif ()

set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

SET(EASY_GRPC_BUILD_EXAMPLES ON CACHE BOOL "easy_grpc examples")
SET(EASY_GRPC_BUILD_TESTS ON CACHE BOOL "easy_grpc tests")

add_subdirectory(protoc_plugin)


add_library(easy_grpc
  src/easy_grpc/client/credentials.cpp
  src/easy_grpc/client/unsecure_channel.cpp
  src/easy_grpc/client/secure_channel.cpp
  
  src/easy_grpc/server/credentials.cpp
  src/easy_grpc/server/context.cpp
  src/easy_grpc/server/server.cpp
  src/easy_grpc/server/service.cpp
  
  src/easy_grpc/environment.cpp
  src/easy_grpc/completion_queue.cpp
)

if(MSVC)
  target_compile_options(easy_grpc PUBLIC /W4 /WX)
else()
  target_compile_options(easy_grpc PUBLIC -Wall -Wextra -pedantic -Werror)
endif()

target_compile_features(easy_grpc PUBLIC cxx_std_17)

target_include_directories(easy_grpc
  PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
  PRIVATE 
    src
)

target_link_libraries(easy_grpc
  gRPC::grpc
  var_futures
  Threads::Threads
  z
)

install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(TARGETS easy_grpc
  EXPORT   easy_grpcTargets
  ARCHIVE  DESTINATION lib
  LIBRARY  DESTINATION lib
  RUNTIME  DESTINATION bin
)

add_subdirectory(src/easy_grpc_reflection)

if(EASY_GRPC_BUILD_EXAMPLES)
  find_package(Protobuf REQUIRED)

  add_subdirectory(examples/00_hello_rpc)
  add_subdirectory(examples/01_non_protobuf)
  add_subdirectory(examples/02_streaming_reply)
  add_subdirectory(examples/03_streaming_request)
endif()

if(EASY_GRPC_BUILD_TESTS)
  add_subdirectory(tests)
endif()

set(export_dest_dir "${CMAKE_INSTALL_LIBDIR}/easy_grpc/cmake")

install(
  EXPORT 
    easy_grpcTargets 
  DESTINATION 
    lib/cmake/easy_grpc)

#install cmake export
install(EXPORT easy_grpcTargets DESTINATION ${export_dest_dir})

configure_file(cmake/easy_grpc-config.cmake.in
  "${PROJECT_BINARY_DIR}/easy_grpc-config.cmake" @ONLY)

install(FILES "${PROJECT_BINARY_DIR}/easy_grpc-config.cmake" DESTINATION "${export_dest_dir}")
############################ code format ############################
if(${EASY_GRPC_MASTER_PROJECT})
  if(NOT DEFINED CLANG_FORMAT_BIN)
    find_program(CLANG_FORMAT_BIN NAMES clang-format)
  endif()

  file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h *.cxx *.hxx *.hpp *.cc *.ipp)

  set(CLANG_FORMAT_EXCLUDE_PATTERNS ${CLANG_FORMAT_EXCLUDE_PATTERNS} 
    "/CMakeFiles/" 
    "cmake"
  )

  foreach (SOURCE_FILE ${ALL_SOURCE_FILES})
      foreach (EXCLUDE_PATTERN ${CLANG_FORMAT_EXCLUDE_PATTERNS})
          string(FIND ${SOURCE_FILE} ${EXCLUDE_PATTERN} EXCLUDE_FOUND)
          if (NOT ${EXCLUDE_FOUND} EQUAL -1)
              list(REMOVE_ITEM ALL_SOURCE_FILES ${SOURCE_FILE})
          endif ()
      endforeach ()
  endforeach ()


  add_custom_target(format
      COMMENT "Running clang-format to change files"
      COMMAND ${CLANG_FORMAT_BIN}
      -style=file
      -i
      ${ALL_SOURCE_FILES}
  )
endif()
#############################################################
